Add a draft security threat model (THREAT_MODEL.md) + SECURITY.md + discoverability wiring#1224
Add a draft security threat model (THREAT_MODEL.md) + SECURITY.md + discoverability wiring#1224potiuk wants to merge 1 commit into
Conversation
…iscoverability wiring Generated-by: Claude Code
|
|
||
| | Family | Repo | Language | Representative entry point | Touches outside the process? | In model? | | ||
| | --- | --- | --- | --- | --- | --- | | ||
| | **guacd core + libguac** | guacamole-server | C | TCP `:4822`, Guacamole-protocol parser, plugin loader | Yes — outbound TCP to remote servers; loads `.so` plugins | **Yes** — primary memory-safety surface | |
There was a problem hiding this comment.
Should we specify the incoming connection from guacamole-client?
There was a problem hiding this comment.
I'm not sure it should call out the inbound connection specifically from guacamole-client, since we do advertise/support it as a more generic Guacamole Protocol proxy that can support custom front-ends, but inbound from a client is probably worth noting.
necouchman
left a comment
There was a problem hiding this comment.
Okay, several comments from me - apologies in advance if any of these are nonsensical.
| be modeled separately because they live at very different trust levels and are | ||
| written in different languages: **guacd**, a C daemon (`apache/guacamole-server`) | ||
| that actually speaks the remote-desktop protocols and translates them to and from | ||
| the text-based *Guacamole protocol*; and the **web application**, a Java servlet |
There was a problem hiding this comment.
Is text-based the best wording, here? I ask because, while we do deliver most of the protocol over text, we also deliver images??
| *(documented — introduction)*. Guacamole is a *deployed network service operated | ||
| by an administrator*, not an in-process library. |
There was a problem hiding this comment.
While this captures the overall scope of the project, I wonder how this statement applies to folks who use the libguac portion of the guacamole-server project, or the guacamole-common and guacamole-common-js portions of the guacamole-client project? How does the fact that we do provide those as libraries that can be used by third party projects relate to our documentation of the thread model?
| *(inferred — I6)*. | ||
| - **guacd exposed directly to untrusted networks.** guacd is designed to sit behind | ||
| the web app on a trusted network segment; a deployment that publishes `:4822` to | ||
| the Internet is a misconfiguration, not a scenario we defend (see §9, §10) |
There was a problem hiding this comment.
I would replace the Internet with any un-trusted network or something similar - while the Internet may be the ultimate example of an un-trusted network, it is certainly not the only example, and publishing guacd port 4822 to any users or systems that should not have direct proxy access through guacd to your remote systems is a violation of the design principles of the software.
| browser ──HTTPS/tunnel──▶ web app (Java) ──TCP :4822──▶ guacd (C) ──RDP/VNC/SSH──▶ remote server | ||
| ▲ │ | ||
| └───────────── Guacamole protocol (rendered images/audio/clipboard) ◀──────────────────────┘ |
There was a problem hiding this comment.
This is not quite accurate - I don't know how much it matters, but, taken at face value, this states that the remote server will speak Guacamole protocol directly to the user's browser, which is not how it works. I'm not entirely sure how to diagram this best in a Github comment, but:
- All traffic from the user's browser passes through the HTTP(S)/WS(S) tunnel back to the Java application, which handles both API calls used for authentication, authorization, and auditing, but also handles the establishment and maintenance of the HTTP(S)/WS(S) tunnel back to guacd. The only traffic that the user's browser will ever see will be between it and the Web Application host(s).
- The traffic to/from the user's browser, tunneled over HTTP(S)/WS(S) by the web application will land at the guacd application, which does all of the translation between the Guacamole protocol and the remote protocols.
- The remote server will only ever see traffic from and send traffic to the guacd instance - there is no direct path from the remote server back to the user's browser. That traffic traverses the same path back - from remote server to guacd, then from guacd back through the tunnel maintenance by the web application, where it is then delivered to the user's browser.
| 4. **guacd/web app → identity & storage backends.** LDAP/SAML/DB/RADIUS lookups | ||
| during authentication, and connection-credential storage/retrieval *(documented | ||
| — introduction lists the extensions; inferred as to trust treatment — I9)*. |
There was a problem hiding this comment.
Slight clarification, here - guacd does not store anything outside of memory. The only credential lookups and storage are done by the web application, which 1) authenticates the users, 2) provides authorization for connections, 3) documents the connections, 4) stores and looks up connection details, potentially including credentials, 5) requests additional credentials from the user, when required, and then 6) delivers the connection information to guacd. guacd only "stores" any of this information in-memory, and only for the duration of the connection, after which it is discarded.
| 11. **(I18) `guacd-ssl` provides transport encryption but not, by itself, mutual | ||
| authentication of the web app to guacd (false friend).** Proposed: correct — | ||
| confirm whether any mutual-auth mechanism exists on this link. *Lands in §9.* |
There was a problem hiding this comment.
This is correct - there is currently no mutual authentication implemented native to the web app <-> guacd components. It can be implemented with, for example, SSH or SSL tunneling configured with additional components, but that is out of scope of this model.
| 12. **(I11/I13) guacd runs as a forking POSIX daemon, does not treat environment | ||
| variables as a trust input, does not phone home, and confines outbound | ||
| connections to operator-defined targets; guacd and the web app are expected to | ||
| run matching patched versions.** Proposed: correct — this negative-side-effects | ||
| inventory is the one most needing maintainer confirmation. *Lands in §5.* |
There was a problem hiding this comment.
Correct...mostly...I think. We do support running different versions of web application and guacd, and have built in some mechanisms to handle negotiation of features between those versions; however, this is strictly designed to handle feature differences, and no guarantee is provided that doing so will be "safe".
| 13. **(I17) Resource guarantees: is there *any* categorical line on DoS from a | ||
| hostile remote stream or a client opening many tunnels — e.g. "a crash/UAF is a | ||
| bug, but sustained CPU/bandwidth from a connected server is not"?** Proposed: no | ||
| categorical resource guarantee at this layer; memory-safety failures remain | ||
| bugs. *Lands in §8/§9/§11a.* |
There was a problem hiding this comment.
I do not believe there are any resource guarantees at this time - it is up to the operator to monitor and throttle resource utilization.
| 14. **(I7/I10) Third-party protocol libraries (FreeRDP/libVNCserver/libssh2/Cairo, | ||
| bundled JS) are modeled only at the boundary where we hand them data; internal | ||
| CVEs are triaged upstream. Reachability preconditions per §4 are the triage | ||
| test.** Proposed: correct. *Lands in §3/§4.* |
| 15. **Document ownership & coexistence.** There is currently **no `SECURITY.md` in | ||
| either code repository** — the sole published security artifact is the website | ||
| security page. Proposed: this threat model becomes the canonical model that the | ||
| security page (and new `SECURITY.md` files in both repos) link to. Confirm the | ||
| venue and whether the PMC wants the machine-readable §15 sidecar. *Meta — no | ||
| body claim.* |
There was a problem hiding this comment.
I'm okay with the proposed solution, but ultimately will leave it to @mike-jumper to decide on that.
necouchman
left a comment
There was a problem hiding this comment.
Okay, several comments from me - apologies in advance if any of these are nonsensical.
This is a proposal for the Guacamole PMC to review — please correct, reject, or discuss as needed. The PMC owns the document; nothing here is a requirement.
This adds a draft umbrella
THREAT_MODEL.mdfor the Apache Guacamole family, aSECURITY.md(the code repos don't currently carry one — the security policy lives only at guacamole.apache.org/security), and anAGENTS.mdwiringAGENTS.md -> SECURITY.md -> THREAT_MODEL.mdso an automated scanner can mechanically discover it. Path 3 as agreed on the list (we draft the v0, the PMC reviews). It lands on apache/guacamole-client as the canonical home; guacamole-server and guacamole-website get small pointer PRs to it once you're happy with the shape.Generated from Guacamole's public artefacts (the security page, docs, advisory history) via the
threat-model-producerrubric. Provenance-tagged throughout; every (inferred) claim routes to a numbered §14 question (15 of them).The model's spine is the guacd(C) / client(Java) / website(static) split:
Two calls we'd especially value your confirmation on (both in §14 wave 1): (1) guacd is not an auth boundary and must be kept off untrusted networks — a report against an exposed
:4822is a misconfiguration, not an in-model bug; (2) the plaintext/unauthenticated webapp↔guacd default (guacd-ssloff on a trusted segment) as the supported production posture.What's most useful: walk the §14 questions and confirm / correct / strike each — a one-liner each is enough. This PR only adds files; it edits no existing content.
Context: the ASF Security team is preparing projects for an automated agentic security scan we're piloting; discoverability is the one hard prerequisite.